import { Modifier, SoldOut } from './../model/clerkDataContext';
import { tableDefine } from './../model/tableDefine';
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { ServiceBase } from "./serviceBase";
import { ClerkDataContext, Inventory, Category, DataContextManager, SyncDataUrl } from "../model/clerkDataContext";
import { QueueManager } from '../common/queueManager';

@Injectable()
export class SyncDataService extends ServiceBase {
    constructor(protected http: Http) { super(); }

    /**
     * 是否支持localCache
     * 
     * @readonly
     * @private
     * 
     * @memberOf SyncDataService
     */
    private get isLocalCacheAvailable() {
        return (<any>window).localCache && (<any>window).localCache.isLocalCacheAvailable();
    }

    async HasAnyData() {
        let ctx = DataContextManager.Current.ClerkCtx;
        let cCount = await ctx.Category.Count();
        let iCount = await ctx.Inventory.Count();
        if (cCount == 0 || iCount == 0) return false;
        return true;
    }

    SyncInventoryData(inventory) {
        let ctx = DataContextManager.Current.ClerkCtx;
        let that = this;
        let promise = new Promise((resolve, reject) => {
            if (this.isLocalCacheAvailable) {
                if (inventory.pic) {
                    let matches = inventory.pic.match("data:(.*);base64,(.*)");
                    if (!matches) {
                        resolve(inventory);
                        return;
                    }
                    (<any>window).localCache.setContent('/api/stores/' + this.CurrentStore.id + '/inventories/' + inventory.id + '/pic/bin', matches[1], matches[2], function (err) {
                        if (err) {
                            console.log("本地缓存图片-", err);
                        }
                        resolve(inventory);
                    });
                } else {
                    resolve(inventory);
                }
            } else {
                resolve(inventory);
            }
        });
        return promise;
    }

    async SyncCategoryData() {
        let url = "api/dataSync/categories/" + this.CurrentStore.id;
        let ctx = DataContextManager.Current.ClerkCtx;

        let result: Category[] = await this.Get(url);
        if (result && result.length) {
            result.forEach(x => {
                let category = new Category();
                category = category.clone(x, category);
                ctx.Create(category);
            });
        }
    }

    async syncResources() {
        let url = "api/dataSync/resourceList/" + this.CurrentStore.id;
        let ctx = DataContextManager.Current.ClerkCtx;

        let result = await this.Get(url);
        if (result && result.length) {
            return result;
        }
        return [];
    }

    async ClearAll() {
        let ctx = DataContextManager.Current.ClerkCtx;
        for (let item of tableDefine) {
            await ctx.Clear(item.TableName);
        }
    }

    /**
     * 查询并保存同步的数据
     * @param  {SyncDataUrl} syncDataUrl 保存需同步的url的数据
     */
    async SaveSynchroData(syncDataUrl: SyncDataUrl) {
        if (!syncDataUrl) {
            return;
        }
        let ctx = DataContextManager.Current.ClerkCtx;
        QueueManager.Current.Add((async () => {
            let result;
            try {
                result = await this.Get(syncDataUrl.url);
                switch (syncDataUrl.type) {
                    case "category":
                        let category = new Category();
                        category = category.clone(result, category);
                        await ctx.Create(category);
                        break;
                    case "inventory":
                        let inventory = new Inventory();
                        inventory = inventory.clone(result, inventory);
                        let invt = await this.SyncInventoryData(inventory);
                        if (this.isLocalCacheAvailable) {
                            if ((<any>window).localCache.exists("/api/stores/" + this.CurrentStore.id + "/inventories/" + (<any>invt).id + "/pic/bin")) {
                                (<any>invt).pic = "/local-cache/api/stores/" + this.CurrentStore.id + "/inventories/" + (<any>invt).id + "/pic/bin";
                            }
                        }
                        await ctx.Create(<any>invt);
                        break;
                    case "modifier":
                        let modifier = new Modifier();
                        modifier = modifier.clone(result, modifier);
                        await ctx.Create(modifier);
                        break;
                    case "soldout":
                        let soldOut = new SoldOut();
                        soldOut = soldOut.clone(result, soldOut);
                        await ctx.Create(soldOut);
                        break;
                    default:
                        break;
                }
                syncDataUrl.complete = true;
            } catch (e) {
                console.log(e);
            }
        }).bind(this));
    }

    private UpdateOrSaveObj(flag, obj, ctx) {
        if (flag) {
            ctx.Update(obj);
        } else {
            ctx.Create(obj);
        }
    }
}
